﻿using System.AutoUpdate.Core;
using System.AutoUpdate.Core.Operations;
using System.AutoUpdate.Extensions;
using System.AutoUpdate.Library;
using System.ComponentModel;
using System.IO;

namespace System.AutoUpdate.Operations
{
    /// <summary>
    /// Operation extract update files and prepares 
    /// </summary>
    public class PrepareOperation : BackgroundOperation
    {
        public override bool StartOperation(UpdateInfo info)
        {
            if (info == null)
            {
                return false;
            }

            Info = info;

            //
            // If we do not have application directory set, we cannot update
            //

            if (!(Directory.Exists(Info.ApplicationRoot)) || (DirectoryExtensions.CanWrite(info.ApplicationRoot)))
            {
                return false;
            }

            //
            // We require the temp directory, because we only prepare files
            //

            if ((Directory.Exists(Info.TemporaryDirectory)) && (DirectoryExtensions.CanWrite(info.TemporaryDirectory)))
            {
                OperationEvent(Core.OperationEvent.Started, this, new OperationEventArgs());

                Run();

                return true;
            }

            return false;
        }

        protected override void WorkerOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            //
            // Create package
            //

            UpdatePackage package = new UpdatePackage(Info.TemporaryDirectory);

            //
            // Open patches in update info and extract them into temporary directory
            //

            foreach (UpdateVersionInfo version in Info.AvailableVersions)
            {
                package.Extract(version.File.AbsoluteLocalPath);
            }

            //
            // Prepare update package
            //

            package.Prepare();

            //
            // Create backup of the files
            //

            package.PrepareRollback(Info.ApplicationRoot);

            //
            // Sets update package, so we can 
            //

            Info.UpdatePackage = package;
        }
    }
}
